package com.thesis.manage.service.impl;

import com.github.crab2died.ExcelUtils;
import com.github.pagehelper.PageInfo;
import com.thesis.manage.common.constant.YesOrNoEnum;
import com.thesis.manage.common.exception.CommonException;
import com.thesis.manage.common.service.impl.BaseServiceImpl;
import com.thesis.manage.domain.College;
import com.thesis.manage.domain.Major;
import com.thesis.manage.mapper.MajorMapper;
import com.thesis.manage.service.ClassesService;
import com.thesis.manage.service.CollegeService;
import com.thesis.manage.service.MajorService;
import com.thesis.manage.service.constant.ErrorMessage;
import com.thesis.manage.service.module.excel.MajorExcel;
import com.thesis.manage.service.module.vo.MajorVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.common.Mapper;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author php
 * @date 2018/1/18
 */
@Service
@Slf4j
public class MajorServiceImpl extends BaseServiceImpl<Major> implements MajorService {
    @Resource
    private MajorMapper majorMapper;

    @Resource
    private CollegeService collegeService;

    @Resource
    private ClassesService classesService;

    @Override
    protected Mapper<Major> getMapper() {
        return this.majorMapper;
    }

    @Override
    protected Class<Major> getEntityClass() {
        return Major.class;
    }

    @Override
    public Integer save(Major major) {
        Assert.notNull(major, ErrorMessage.OBJECT_NO_INSTANCE);
        if (major.getId() != null) {
            if (major.getCollegeId() != null) {
                College college = this.collegeService.findById(major.getCollegeId());
                if (college != null) {
                    major.setCollegeName(college.getName());
                }
            }
            major.setEndTime(new Date());
            this.majorMapper.updateByPrimaryKeySelective(major);
        } else {
            Assert.notNull(major.getName(), ErrorMessage.PARAMS_IS_NULL);
            /*
            查询专业对应院系名
             */
            College college = new College();
            if (major.getCollegeId() != null) {
                college = this.collegeService.findById(major.getCollegeId());
            } else if (StringUtils.isNotBlank(major.getCollegeName())) {
                College query = new College();
                query.setName(major.getCollegeName());
                college = this.collegeService.findByOne(query);
            }
            if (college != null) {
                major.setStartTime(new Date());
                major.setEndTime(major.getStartTime());
                major.setDelStatus(YesOrNoEnum.NO.getValue());
                major.setCollegeName(college.getName());
                major.setCollegeId(college.getId());
            }
            this.majorMapper.insert(major);
        }
        return major.getId().intValue();
    }

    @Override
    public void importExcel(MultipartFile file) {
        Assert.notNull(file, ErrorMessage.REQUEST_SELECT_FILE);
        try {
            List<MajorExcel> majorExcels = ExcelUtils.getInstance().readExcel2Objects(file.getInputStream(), MajorExcel.class);
            /*
            对象转换
             */
            if (CollectionUtils.isNotEmpty(majorExcels)) {
                Major major;
                for (MajorExcel majorExcel : majorExcels) {
                    major = new Major();
                    PropertyUtils.copyProperties(major, majorExcel);
                    boolean isSave = StringUtils.isNotBlank(major.getName()) && StringUtils.isNotBlank(major.getCollegeName()) && this.isNotExist(major.getName());
                    if (isSave) {
                        this.save(major);
                        this.classesService.importData(majorExcel.getClassesInfo(), major.getId());
                    }
                }
            }
        } catch (Exception e) {
            log.error("file import failed,{}", e.getMessage());
            throw new CommonException("file import failed", ErrorMessage.FILE_IMPORT_FAILED);
        }
    }

    @Override
    public void export(HttpServletResponse response) {
        try {
            String name = "专业信息.xlsx";
            // 设置response参数，可以打开下载页面
            response.setContentType("application/vnd.ms-excel;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(name.getBytes(), "iso-8859-1"));
            ServletOutputStream out = response.getOutputStream();
            Major major = new Major();
            major.setDelStatus(YesOrNoEnum.NO.getValue());
            List<Major> list = this.majorMapper.select(major);
            List<MajorExcel> result = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(list)) {
                MajorExcel majorExcel;
                for (Major m : list) {
                    majorExcel = new MajorExcel();
                    majorExcel.setCollegeName(m.getCollegeName());
                    majorExcel.setName(m.getName());
                    majorExcel.setRemark(m.getRemark());
                    List<String> classNames = this.classesService.findClassNamesByMajorId(m.getId());
                    if (CollectionUtils.isNotEmpty(classNames)) {
                        for (String s : classNames) {
                            majorExcel.setClassesInfo(s);
                            result.add(majorExcel);
                        }
                    } else {
                        result.add(majorExcel);
                    }
                }
                ExcelUtils.getInstance().exportObjects2Excel(result, MajorExcel.class, true, "sheet0", true, out);
            }
        } catch (Exception e) {
            log.error("file export failed,{}", e.getMessage());
            throw new CommonException("file export failed", ErrorMessage.FILE_EXPORT_ERROR);
        }
    }

    @Override
    public MajorVO findInfoById(Long id) {
        MajorVO majorVO = new MajorVO();
        Major major = this.findById(id);
        Assert.notNull(major, ErrorMessage.DATA_NO_EXIST);
        List<String> classesList = this.classesService.findClassNamesByMajorId(id);
        try {
            PropertyUtils.copyProperties(majorVO, major);
            majorVO.setClassNames(classesList);
        } catch (Exception e) {
            log.error("object convert failed,{}", e.getMessage());
            throw new CommonException("object convert failed", ErrorMessage.OBJECT_CONVERT_FAILED);
        }
        return majorVO;
    }

    @Override
    public PageInfo<MajorVO> detailInfo(Pageable pageable) {
        List<MajorVO> majorVOS = new ArrayList<>();
        PageInfo<Major> list = this.list(pageable);
        if (CollectionUtils.isNotEmpty(list.getList())) {
            for (Major major : list.getList()) {
                MajorVO majorVO = this.findInfoById(major.getId());
                majorVOS.add(majorVO);
            }
        }
        PageInfo<MajorVO> objectPageInfo = new PageInfo<>();
        objectPageInfo.setTotal(list.getTotal());
        objectPageInfo.setList(majorVOS);
        objectPageInfo.setPageNum(list.getPageNum());
        objectPageInfo.setPageSize(list.getPageSize());
        objectPageInfo.setPages(list.getPages());
        return objectPageInfo;
    }

    @Override
    public Major findByName(String majorName) {
        Major major = new Major();
        major.setName(majorName);
        return this.findByOne(major);
    }

    /**
     * 验证院系是否存在
     *
     * @param name 院系名称
     * @return boolean
     */
    private boolean isNotExist(String name) {
        Major major = new Major();
        major.setName(name);
        major.setDelStatus(YesOrNoEnum.NO.getValue());
        return this.majorMapper.selectOne(major) == null;
    }

//    /**
//     * 对象转换
//     *
//     * @param majorExcels 转换对象
//     * @return list<Major>
//     */
//    private List<Major> convert(List<MajorExcel> majorExcels) {
//        List<Major> list = new ArrayList<>();
//        try {
//            if (CollectionUtils.isNotEmpty(majorExcels)) {
//                Major major;
//                for (MajorExcel majorExcel : majorExcels) {
//                    major = new Major();
//                    PropertyUtils.copyProperties(major, majorExcel);
//                    list.add(major);
//                }
//            }
//            return list;
//        } catch (Exception e) {
//            throw new CommonException("object covert failed", ErrorMessage.OBJECT_CONVERT_FAILED);
//        }
//    }
}
